package com.syh.jn.scm.domain.supplier.entity.finance.archive;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import cn.redscarf.commons.wrapper.expression.orderExpression.Order;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.repository.finance.archive.ArchiveRepository;
import com.syh.jn.scm.dto.supplier.finance.archive.ArchiveSto;
import com.syh.jn.scm.dto.supplier.statistics.finance.SettlementsReportVo;
import com.syh.jn.scm.dto.supplier.statistics.stock.InventoryReportVo;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.infrastructure.repository.utils.MybatisTemplate;
import com.syh.jn.scm.service.api.supplier.logistics.enums.LogisticsBillEnums;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by soci.song on 2019/3/1.
 */
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Archive extends AbstractSimpleAggregate<Long> {

  public Archive(ArchiveSto sto) {
    ExtBeanUtils.copyProperties(sto,this);
    this.initDefault();
    this.createItems();
    this.summary();
  }

  @Override
  protected void initDefault() {
    super.initDefault();
    this.receivablesSummary = BigDecimal.ZERO;
    this.payablesSummary = BigDecimal.ZERO;
    this.stockBalanceSummary = BigDecimal.ZERO;
    this.beginningReceivablesSummary = BigDecimal.ZERO;
    this.beginningPayablesSummary = BigDecimal.ZERO;
    this.beginningStockBalanceSummary = BigDecimal.ZERO;
  }

  private void createItems(){

    ArchiveRepository readRepository = (ArchiveRepository) SpringContextUtils.getBean(ArchiveRepository.class);
    Wrapper we = Wrapper.build();
    we.append(Restrictions.eq("businessEntityId",this.businessEntityId));
    we.order(Order.desc("archiveEndTimeStamp"));
    Archive vo = readRepository.getOne(we);

    if(vo != null && vo.getArchiveEndTimeStamp() >= this.archiveEndTimeStamp)
      throw new BusinessException("结存时间不能小于、等于往期结存时间！");

    //报表查询，统计时间段内的应收付
    Map<String,Object> parms = new HashMap<>();
    parms.put("businessEntityId",this.businessEntityId);
    parms.put("beginTime",vo == null ? 1 : vo.getArchiveEndTimeStamp());
    parms.put("endTime",this.archiveEndTimeStamp);
    parms.put("startRow",0);
    parms.put("pageSize",Integer.MAX_VALUE);
    List<SettlementsReportVo> settlemtnsList = MybatisTemplate.selectList("financeSettlementsRepository.settlementsReport",parms);
    //创建items
    this.settlementsItems = new ArrayList<>();
    settlemtnsList.forEach(settlemtns->{
      this.settlementsItems.add(new ArchiveSettlements(settlemtns));
    });

    //报表查询，统计时间段内的库存
    List<InventoryReportVo> stockList = MybatisTemplate.selectList("stockInventoryQRepository.inventoryReport",parms);
    //创建items
    this.stockItems = new ArrayList<>();
    stockList.forEach(stock->{
      this.stockItems.add(new ArchiveStock(stock));
    });
  }

  private void summary() {
    this.settlementsItems.forEach(item ->{
      //采购商汇总应收款
      if(item.getCustomerType().equals(LogisticsBillEnums.CustomerType.DOWNSTREAM.getStatus())){
        this.receivablesSummary = this.receivablesSummary.add(item.getTotalShouldSettlements())
                .subtract(item.getTotalAlreadySettlements());
        this.beginningReceivablesSummary = this.beginningReceivablesSummary.add(item.getBeginningShouldSettlements())
                .subtract(item.getBeginningAlreadySettlements());
      }
      //供应商、物流公司汇总应付款
      else{
        this.payablesSummary = this.payablesSummary.add(item.getTotalShouldSettlements())
                .subtract(item.getTotalAlreadySettlements());
        this.beginningPayablesSummary = this.beginningPayablesSummary.add(item.getBeginningShouldSettlements())
                .subtract(item.getBeginningAlreadySettlements());
      }
    });

    this.stockItems.forEach(item ->{
      //汇总库存余额
      this.stockBalanceSummary = this.stockBalanceSummary.add(item.getTotalBalance());
      this.beginningStockBalanceSummary = this.beginningStockBalanceSummary.add(item.getBeginningBalance());
    });
  }

  public void cancel() {
    ArchiveRepository readRepository = (ArchiveRepository) SpringContextUtils.getBean(ArchiveRepository.class);
    Wrapper we = Wrapper.build();
    we.append(Restrictions.gt("archiveEndTimeStamp",this.archiveEndTimeStamp));
    Archive vo = readRepository.getOne(we);
    if(vo != null)
      throw new BusinessException("反结存记录存在下期，请按结存时间倒序反结存！");
  }

  /**
   * 数据归属公司ID
   */
  protected Long businessEntityId;
  /**
   * 结存开始日期
   */
  private Long archiveFromTimeStamp;
  /**
   * 结存结束日期
   */
  private Long archiveEndTimeStamp;
  /**
   * 应收汇总
   */
  private BigDecimal receivablesSummary;
  /**
   * 应付汇总
   */
  private BigDecimal payablesSummary;
  /**
   * 库存余额汇总
   */
  private BigDecimal stockBalanceSummary;
  /**
   * 期初应收汇总
   */
  private BigDecimal beginningReceivablesSummary;
  /**
   * 期初应付汇总
   */
  private BigDecimal beginningPayablesSummary;
  /**
   * 期初库存余额汇总
   */
  private BigDecimal beginningStockBalanceSummary;
  /**
   * 结存标题
   */
  private String title;
  /**
   * 结存备注
   */
  private String remark;
  /**
   * 操作人员id
   */
  private Long operatorId;
  /**
   *settlementsItems
   */
  private List<ArchiveSettlements> settlementsItems;
  /**
   *stockItems
   */
  private List<ArchiveStock> stockItems;

}
